package com.firefly.curve;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.Rectangle2D;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;

import com.firefly.curve.attr.Area;
import com.firefly.curve.attr.Margin;
import com.firefly.curve.attr.Scale;
import com.firefly.curve.attr.StringRec;
import com.firefly.curve.listener.CurveListener;
import com.firefly.curve.listener.CurveMouseListener;

public class CurvePanel extends JPanel implements MouseListener, MouseMotionListener,MouseWheelListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final int AXIS_WIDTH=4;//刻度宽度
	private static final int GRID_WIDDTH=1;//网格宽度
	private static final int SCALE_LEN=20;//刻度长度
	private static final int SCALE_WIDTH=2;//刻度宽度
	private static final int SCALE_LEN_SMALL=10;//小刻度长度
	private static final int SCALE_WIDTH_SMALL=2;//小刻度宽度
	
	private List<CurveListener> listeners=new ArrayList<CurveListener>();
	private List<CurveMouseListener> curveMouseListeners=new ArrayList<CurveMouseListener>();
	private Margin margin=new Margin(60,60,10,40);//边缘间隔
	private Scale axisX=new Scale(0,2000,10);//X轴刻度
	private Scale axisY=new Scale(0,100,10);//Y轴刻度
	private String xUnit="m";
	private String yUnit="℃";
	private Font xUnitFont=new Font("TimesRoman",Font.BOLD,16);
	private Font yUnitFont=new Font("TimesRoman",Font.BOLD,16);
	private Color xUnitColor=Color.black;
	private Color yUnitColor=Color.black;
	private Color scaleXColor=Color.black;
	private Font scaleXFont=new Font("TimesRoman",Font.BOLD,12);
	private Color scaleYColor=Color.black;
	private Font scaleYFont=new Font("TimesRoman",Font.BOLD,12);
	float axisXBase=1;
	float axisYBase=1;
	private Scale axisXCurrent=new Scale(0,2000,10);//X轴刻度
	private Scale axisYCurrent=new Scale(0,100,10);//Y轴刻度
	private Graphics graphics=null;
	private Area selectArea=new Area();
	private Color selectAreaColor=Color.gray;
	private boolean isMousePressed=false;//是否鼠标按下
	
	private DecimalFormat scaleFormat = new DecimalFormat("0.##");//刻度值格式
	private String toolTipText="";
	private Color toolTipTextColor=Color.black;
	private Font toolTipTextFont=new Font("TimesRoman",Font.BOLD,16);
	
	private String title="";
	private Color titleColor=Color.black;
	private Font titleFont=new Font("TimesRoman",Font.BOLD,20);
	
	private String titleRight="";
	private Color titleRightColor=Color.black;
	private Font titleRightFont=new Font("TimesRoman",Font.BOLD,16);
	
	private String explainText="";
	private Color explainTextColor=Color.black;
	private Font explainTextFont=new Font("TimesRoman",Font.BOLD,16);
	
	private boolean showCross=false;//是否显示十字
	private Color crossAcrossColor=Color.black;//横轴颜色
	private Color crossVerticalColor=Color.black;//纵轴颜色
	private Color crossAcrossTextColor=Color.black;//横轴文本颜色
	private Color crossVerticalTextColor=Color.black;//纵轴文本颜色
	private DecimalFormat crossTextFormat = new DecimalFormat("0.##");//刻度值格式
	private Font crossFont=new Font("TimesRoman",Font.BOLD,16);

	//颜色属性
	//刻度颜色
	private Color axisXColor=Color.black;
	private Color axisYColor=Color.black;
	//网格颜色
	private Color gridXColor=Color.gray;
	private Color gridYColor=Color.gray;
	
	public CurvePanel(){
		//设置背景颜色
		this.setBackground(Color.white);
		
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
		this.addMouseWheelListener(this);
	}
	
	@Override
	protected void paintComponent(Graphics g) {
//		long between = 0;
//        Date begin=null;
//        try {
//            begin = new Date();
//        } catch (Exception ex) {
//            ex.printStackTrace();
//        }
        
		super.paintComponent(g);
		
		calcAxisBase();//计算基础刻度

		graphics=g;
		
		Graphics2D g2d = (Graphics2D)g;
		Stroke defaultStroke=g2d.getStroke();
		
		g2d.translate(margin.getLeft(), this.getHeight()-margin.getBottom());//设置坐标位置
        g2d.scale(1, -1);//设置坐标放大倍数和坐标方向
        
        //画网格
        drawGrid(g);
        
        //画曲线
        for(CurveListener listener:listeners){
        	g2d.setStroke(defaultStroke);//默认笔
        	listener.draw(this,g);//画曲线
        }
        
        //画选择框
        if(isMousePressed){
        	showSelectRect(g);
        }
        
        drawCross(g);//画十字架
        
        //显示提示框
        showToolTipText(g);
        
        //清除画图四周的区域
        clearOtherArea(g);
        
        //画文本
        drawString(g);
        
        //画刻度
        drawAxis(g);
        //画单位
        drawUnit(g);
        
//        try {
//            Date end = new Date();
//            between = (end.getTime() - begin.getTime());// 得到两者的毫秒数
//            System.out.println(between);
//        } catch (Exception ex) {
//            ex.printStackTrace();
//        }
	}
	
	private void showToolTipText(Graphics g){
		if(!"".equals(toolTipText)){
			Graphics2D g2d = (Graphics2D)g;
			Font defaultFont=g.getFont();
			g.setFont(toolTipTextFont);
			
			try{
				StringRec strRec=new StringRec(g);
				strRec.setVal(toolTipText);
	            
				int x=selectArea.getX2()-margin.getLeft()+20;
				int y=-(this.curveHeight()-selectArea.getY2()+margin.getTop()-(int)strRec.getLineHeight());
				int strLen=strRec.getWidth();
				
				if((x+strLen+10)>this.curveWidth()){
					x=this.curveWidth()-strLen-10;
				}else if(x<=10){
					x=10;
				}
				if(-y<=10+(int)strRec.getLineHeight()){
					y=-10-(int)strRec.getLineHeight();
				}else if(-y+(int)strRec.getLineHeight()>=this.curveHeight()){
					y=-(this.curveHeight()-(int)strRec.getLineHeight());
				}
				
	        	g.setColor(toolTipTextColor);
	        	g2d.scale(1, -1);//设置坐标放大倍数和坐标方向
	        	strRec.drawString(x,y);
//	        	g.drawRect(x, y-(int)rec2.getHeight(), (int)rec2.getWidth(), (int)rec2.getHeight());
			}finally{
				g2d.scale(1, -1);//设置坐标放大倍数和坐标方向
				g.setFont(defaultFont);
			}
        }
	}
	
	private void showSelectRect(Graphics g){
		Graphics2D g2d = (Graphics2D)g;
		
		BasicStroke stroke = new BasicStroke(1,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL,10.0f,new float[]{3.0f,5.0f},10);
		g2d.setStroke(stroke);
		g.setColor(selectAreaColor);

    	int width=selectArea.getX2()-selectArea.getX1();
    	int height=selectArea.getY2()-selectArea.getY1();
    	int x1=selectArea.getX1()-margin.getLeft();
    	int y1=this.curveHeight()-(selectArea.getY1()-margin.getTop());
    	int x2=selectArea.getX2()-margin.getLeft();
    	int y2=this.curveHeight()-(selectArea.getY2()-margin.getTop());
    	
    	g.drawRect(
    			width>0?x1:x2,
        		height>0?y2:y1,
        		Math.abs(width),
        		Math.abs(height)
        		);
	}
	
	private void drawCross(Graphics g){
		if(showCross){
			Graphics2D g2d = (Graphics2D)g;
			Font defaultFont=g.getFont();
			
			//横轴的Y值
			int axisAcrossY=(this.curveHeight()-selectArea.getY2()+margin.getTop());
			//纵轴的X值
			int axisVerticalX=selectArea.getX2()-margin.getLeft();
			
//			private Color crossAcrossColor=Color.black;//横轴颜色
//			private Color crossVerticalColor=Color.black;//纵轴颜色
//			private Color crossAcrossTextColor=Color.black;//横轴文本颜色
//			private Color crossVerticalTextColor=Color.black;//纵轴文本颜色
			
			if(axisAcrossY<=0){
				axisAcrossY=0;
			}else if(axisAcrossY>=this.curveHeight()){
				axisAcrossY=(this.curveHeight());
			}
			
			if(axisVerticalX<=0){
				axisVerticalX=0;
			}else if(axisVerticalX>=this.curveWidth()){
				axisVerticalX=this.curveWidth();
			}
			
			try{
				g.setColor(crossAcrossColor);
				//画横线
				g.drawLine(0, axisAcrossY, this.curveWidth(), axisAcrossY);
				
				g.setColor(crossVerticalColor);
				//画纵线
				g.drawLine(axisVerticalX, 0, axisVerticalX, this.curveHeight());
				
				//###############################################
				//显示坐标值
				
				g2d.scale(1, -1);//设置坐标放大倍数和坐标方向

				g.setFont(crossFont);
				
				g.setColor(crossAcrossTextColor);
				String showStr=crossTextFormat.format(yToAxisY(selectArea.getY2()));
				StringRec strRec=new StringRec(g);
				strRec.setVal(showStr);
				g.drawString(showStr, 0+(axisVerticalX<=strRec.getWidth()?this.curveWidth()-strRec.getWidth():0), -axisAcrossY+(axisAcrossY+strRec.getHeight()>=this.curveHeight()?strRec.getHeight():0));
				
				g.setColor(crossVerticalTextColor);
				showStr=crossTextFormat.format(xToAxisX(selectArea.getX2()));
				strRec.setVal(showStr);
				g.drawString(showStr, axisVerticalX-(axisVerticalX+strRec.getWidth()>=this.curveWidth()?strRec.getWidth():0), (axisAcrossY+strRec.getHeight()>=this.curveHeight()?0:(-this.curveHeight()+strRec.getHeight())));

			}finally{
				g2d.scale(1, -1);//设置坐标放大倍数和坐标方向
				g.setFont(defaultFont);
			}
		}
	}
	
	private void clearOtherArea(Graphics g){
		//清除画图四周的区域
        g.setColor(getBackground());
        //清除顶部
        g.fillRect(0,this.getHeight()-margin.getTop()-margin.getBottom(),this.getWidth(),margin.getTop());
        //清除底部
        g.fillRect(0,-margin.getBottom(),this.getWidth(),margin.getBottom());
        //清除左边
        g.fillRect(-margin.getLeft(),0,margin.getLeft(),this.getHeight()-margin.getTop()-margin.getBottom());
        //清除右边
        g.fillRect(this.getWidth()-margin.getRight()-margin.getLeft()+GRID_WIDDTH,0,margin.getRight(),this.getHeight()-margin.getTop()-margin.getBottom());
	}
	
	//画刻度
	private void drawAxis(Graphics g){
		Font defaultFont=g.getFont();
		
		float sectionWidth=curveWidth()/axisXCurrent.getSectionNum();///分段宽度
		float sectionHeight=curveHeight()/axisYCurrent.getSectionNum();///分段高度
		float sectionWidthSmall=sectionWidth/5;///小分段宽度
		float sectionHeightSmall=sectionHeight/5;///小分段高度
		float sectionXVal=(axisXCurrent.getEnd()-axisXCurrent.getStart())/axisXCurrent.getSectionNum();
		float sectionYVal=(axisYCurrent.getEnd()-axisYCurrent.getStart())/axisYCurrent.getSectionNum();
		
		Graphics2D g2d = (Graphics2D)g;
		
		try{
			//##################################################
			//画
			BasicStroke stroke = new BasicStroke(AXIS_WIDTH,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL);
			g2d.setStroke(stroke);
			g.setColor(axisYColor);
			//画Y轴
			g.drawLine(0-(AXIS_WIDTH/2), -margin.getBottom(), 0-(AXIS_WIDTH/2), this.getHeight()-margin.getTop()-margin.getBottom());
			g.setColor(axisXColor);
			//画X轴
			g.drawLine(-margin.getLeft(), 0-(AXIS_WIDTH/2),this.getWidth()-margin.getRight()-margin.getLeft(), 0-(AXIS_WIDTH/2));
			//##################################################
			
			//##################################################
			//画大刻度
			//画Y轴的刻度
			stroke = new BasicStroke(SCALE_WIDTH,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL);
			g2d.setStroke(stroke);
			g.setColor(axisYColor);
			for(int i=1;i<=axisYCurrent.getSectionNum();i++){
				//画Y轴
				g.drawLine(0, (int)(i*sectionHeight),-SCALE_LEN , (int)(i*sectionHeight));
			}
			
			//画X轴的刻度
			g.setColor(axisXColor);
			for(int i=1;i<=axisXCurrent.getSectionNum();i++){
				//画X轴
				g.drawLine((int)(i*sectionWidth),0,(int)(i*sectionWidth),-SCALE_LEN);
			}
			//##################################################
			
			//##################################################
			//画小刻度
			stroke = new BasicStroke(SCALE_WIDTH_SMALL,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL);
			g2d.setStroke(stroke);
			g.setColor(axisYColor);
			for(int i=1;i<=axisYCurrent.getSectionNum();i++){
				//画Y轴
				for(int j=1;j<=4;j++){
					g.drawLine(0, (int)(i*sectionHeight-j*sectionHeightSmall),-SCALE_LEN_SMALL , (int)(i*sectionHeight-j*sectionHeightSmall));
				}
			}
			
			//画X轴的刻度
			g.setColor(axisXColor);
			for(int i=1;i<=axisXCurrent.getSectionNum();i++){
				//画X轴
				for(int j=1;j<=4;j++){
					g.drawLine((int)(i*sectionWidth-j*sectionWidthSmall),0,(int)(i*sectionWidth-j*sectionWidthSmall),-SCALE_LEN_SMALL);
				}
			}
			//##################################################
			
			//##################################################
			//标刻度
			try{
				g2d.scale(1, -1);//设置坐标放大倍数和坐标方向
				g.setColor(scaleXColor);
				g.setFont(scaleXFont);
				for(int i=1;i<=axisYCurrent.getSectionNum();i++){
					String str=scaleFormat.format((axisYCurrent.getStart()+sectionYVal*i));
					//获取打印字符的宽和高
					FontMetrics fm2 = g.getFontMetrics();  
		            Rectangle2D rec2=fm2.getStringBounds(str, g);
		            
					g.drawString(str, -((int)rec2.getWidth())-SCALE_LEN+4, -(int)(i*sectionHeight-rec2.getHeight()+4));
				}
				g.setColor(scaleYColor);
				g.setFont(scaleYFont);
				for(int i=1;i<=axisXCurrent.getSectionNum();i++){
					String str=scaleFormat.format((axisXCurrent.getStart()+sectionXVal*i));
					//获取打印字符的宽和高
					FontMetrics fm2 = g.getFontMetrics();  
		            Rectangle2D rec2=fm2.getStringBounds(str, g);
		            
					g.drawString(str, (int)(i*sectionWidth-rec2.getWidth()-4), SCALE_LEN+4);
				}
				
				//##################################################
			}finally{
				g2d.scale(1, -1);//设置坐标放大倍数和坐标方向
				g.setFont(defaultFont);
			}
		}finally{
			
		}
	}
	
	private void drawString(Graphics g){
		Graphics2D g2d = (Graphics2D)g;
		try{
			g2d.scale(1, -1);//设置坐标放大倍数和坐标方向
			g.setColor(titleColor);
			g.setFont(titleFont);
			//获取打印字符的宽和高
			FontMetrics fm2 = g.getFontMetrics();
            Rectangle2D rec2=fm2.getStringBounds(title, g);
			g.drawString(title, (int)((this.curveWidth()-margin.getLeft()-(int)rec2.getWidth())/2),-(this.curveHeight()+(int)((margin.getTop()-rec2.getHeight())/2)));
		
			g.setColor(titleRightColor);
			g.setFont(titleRightFont);
			//获取打印字符的宽和高
			fm2 = g.getFontMetrics();
            rec2=fm2.getStringBounds(titleRight, g);
			g.drawString(titleRight, (int)(this.curveWidth()-(int)rec2.getWidth()),-(this.curveHeight()+(int)((margin.getTop()-rec2.getHeight())/2)));
			
			g.setColor(explainTextColor);
			g.setFont(explainTextFont);
			//获取打印字符的宽和高
			StringRec strRec=new StringRec(g);
			strRec.setVal(explainText);
			strRec.drawString((int)(this.curveWidth()-10-strRec.getWidth()), -(this.curveHeight()-(int)rec2.getHeight()));
//			drawString(g,explainText, (int)(this.curveWidth()-10),-(this.curveHeight()-(int)rec2.getHeight()),-1,0);
			
		}finally{
			g2d.scale(1, -1);//设置坐标放大倍数和坐标方向
		}
	}
	
	private void drawUnit(Graphics g){
		Graphics2D g2d = (Graphics2D)g;
		try{
			g2d.scale(1, -1);//设置坐标放大倍数和坐标方向
			g.setColor(xUnitColor);
			g.setFont(xUnitFont);
			FontMetrics fm2 = g.getFontMetrics();
			//获取打印字符的宽和高
            Rectangle2D rec2=fm2.getStringBounds(xUnit, g);
			g.drawString(xUnit, this.curveWidth()-(int)rec2.getWidth()-20, -10);

			g.setColor(yUnitColor);
			g.setFont(yUnitFont);
			//获取打印字符的宽和高
			fm2 = g.getFontMetrics();
            rec2=fm2.getStringBounds(yUnit, g);
            
			g.drawString(yUnit, 10, -this.curveHeight()+(int)rec2.getHeight()+10);
		}finally{
			g2d.scale(1, -1);//设置坐标放大倍数和坐标方向
		}
	}
	
	//画网格
	private void drawGrid(Graphics g){
		Graphics2D g2d = (Graphics2D)g;
		BasicStroke stroke = new BasicStroke(GRID_WIDDTH,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL,10.0f,new float[]{3.0f,5.0f},10);
		g2d.setStroke(stroke);
		
		float sectionWidth=curveWidth()/axisXCurrent.getSectionNum();///分段宽度
		float sectionHeight=curveHeight()/axisYCurrent.getSectionNum();///分段高度
		
		g.setColor(gridYColor);
		for(int i=1;i<=axisXCurrent.getSectionNum();i++){
			//画Y轴
			g.drawLine((int)(i*sectionWidth), 0, (int)(i*sectionWidth), this.getHeight()-margin.getTop()-margin.getBottom());
		}
		
		g.setColor(gridXColor);
		for(int i=1;i<=axisYCurrent.getSectionNum();i++){
			//画X轴
			g.drawLine(0,(int)(i*sectionHeight),this.getWidth()-margin.getRight()-margin.getLeft(),(int)(i*sectionHeight));
		}
	}
	
	//选择区域
	public void showArea(Area area){
		showArea(area.getX1(),area.getY1(),area.getX2(),area.getY2());
	}
	public void showArea(int x1,int y1,int x2,int y2){
		float start1,end1,start2,end2;
		start1=xToAxisX(x1);
		end1=xToAxisX(x2);
		start2=yToAxisY(y2);
		end2=yToAxisY(y1);
		
		axisXCurrent.setStart(start1);
		axisXCurrent.setEnd(end1);
		
		axisYCurrent.setStart(start2);
		axisYCurrent.setEnd(end2);
	}
	
	public void moveArea(Area area){
		moveArea(area.getX1(),area.getY1(),area.getX2(),area.getY2());
	}
	
	public void moveArea(int x1,int y1,int x2,int y2){
		float x,y;
		x=(x1-x2)*axisXBase;
		y=(y2-y1)*axisYBase;
		
		axisXCurrent.setStart(axisXCurrent.getStart()+x);
		axisXCurrent.setEnd(axisXCurrent.getEnd()+x);
		
		axisYCurrent.setStart(axisYCurrent.getStart()+y);
		axisYCurrent.setEnd(axisYCurrent.getEnd()+y);
	}
	
	public void resetAxis(){
		axisXCurrent.setStart(axisX.getStart());
		axisXCurrent.setEnd(axisX.getEnd());
		
		axisYCurrent.setStart(axisY.getStart());
		axisYCurrent.setEnd(axisY.getEnd());
	}
	
	private int curveHeight(){
		return this.getHeight()-margin.getTop()-margin.getBottom();
	}
	private int curveWidth(){
		return this.getWidth()-margin.getLeft()-margin.getRight();
	}
	
	//计算基础刻度
	private void calcAxisBase(){
		int width=curveWidth();
		int height=curveHeight();
		
		axisXBase=((axisXCurrent.getEnd()-axisXCurrent.getStart())/width);
		axisYBase=((axisYCurrent.getEnd()-axisYCurrent.getStart())/height);
	}
	
	private float xToAxisX(int val){
		return (axisXCurrent.getStart()+(val-margin.getLeft())*axisXBase);
	}
	
	private float yToAxisY(int val){
		return axisYCurrent.getEnd()-((val-margin.getTop())*axisYBase);
	}
	
	private int axisXToX(float val){
		return (int)((val-axisXCurrent.getStart())/axisXBase);
	}
	
	private int axisYToY(float val){
		return (int)((val-axisYCurrent.getStart())/axisYBase);
	}
	
	public void drawLine(float x1,float y1,float x2,float y2){
		if(isShowArea(x1,y1,x2,y2)){
			graphics.drawLine(axisXToX(x1), axisYToY(y1), axisXToX(x2), axisYToY(y2));
//			System.out.println(x2+","+y2);
		}
//		else{
//			System.out.println("超出:["+x1+","+y1+"]["+x2+","+y2+"]");
//		}
	}
	
	//判断是否为可视范围
	@SuppressWarnings("unused")
	private boolean isShowArea(float x,float y){
		if(
				(x>=axisXCurrent.getStart() && x<=axisXCurrent.getEnd())
				&&(y>=axisYCurrent.getStart() && y<=axisYCurrent.getEnd()))
		{
			return true;
		}else{
			return false;
		}
	}
	//判断是否为可视范围
	private boolean isShowArea(float x1,float y1,float x2,float y2){
		if(
				((x1<axisXCurrent.getStart() && x2<axisXCurrent.getStart()) || (y1<axisYCurrent.getStart() && y2<axisYCurrent.getStart()))
				||((x1>axisXCurrent.getEnd() && x2>axisXCurrent.getEnd()) || (y1>axisYCurrent.getEnd() && y2>axisYCurrent.getEnd()))
				)
		{	
			return false;
		}else{
			return true;
		}
	}

	@Override
	public void mouseClicked(MouseEvent e) {
//		System.out.println("mouseClicked");
	}

	@Override
	public void mouseEntered(MouseEvent e) {
//		System.out.println("mouseEntered");
	}

	@Override
	public void mouseExited(MouseEvent e) {
//		System.out.println("mouseExited");
	}

	@Override
	public void mousePressed(MouseEvent e) {
//		if(e.getButton()==MouseEvent.BUTTON1)
		{//左键
			isMousePressed=true;
		}
		selectArea.setX1(e.getX());
		selectArea.setY1(e.getY());
		selectArea.setX2(e.getX());
		selectArea.setY2(e.getY());
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		isMousePressed=false;
		selectArea.setX2(e.getX());
		selectArea.setY2(e.getY());
		
		if(e.getButton()==MouseEvent.BUTTON1){//左键
			if(
					selectArea.getX2()<selectArea.getX1()
					||selectArea.getY2()<selectArea.getY1()
			){
				resetAxis();
			}else if(selectArea.getX2()==selectArea.getX1()
					&&selectArea.getY2()==selectArea.getY1()){
				//没有选择则不理会
			}
			else{
				showArea(selectArea);
			}
		}else if(e.getButton()==MouseEvent.BUTTON3){//右键
			moveArea(selectArea);
		}
		
		this.repaint();
//		System.out.println("mouseReleased");
//		this.repaint();
//		System.out.println("x=" + axisXCurrent.getStart() + "		" + axisXCurrent.getEnd() + "\ny=" + axisYCurrent.getStart() + "		" + axisYCurrent.getEnd() +"\n");
		
	}

	@Override
	public void mouseDragged(MouseEvent e) {
		selectArea.setX2(e.getX());
		selectArea.setY2(e.getY());
		for(CurveMouseListener listener:curveMouseListeners){
			listener.mouseDragged(xToAxisX(e.getX()), yToAxisY(e.getY()));
		}
		this.repaint();
//		System.out.println("mouseDragged");
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		selectArea.setX2(e.getX());
		selectArea.setY2(e.getY());
		for(CurveMouseListener listener:curveMouseListeners){
			listener.mouseMoved(xToAxisX(e.getX()), yToAxisY(e.getY()));
		}
		if(showCross){
			this.repaint();
//			System.out.println("mouseMoved");
		}
	}
	
	//滚轮放大缩小
	@Override
	public void mouseWheelMoved(MouseWheelEvent e) {
		float widthX=axisXCurrent.getEnd()-axisXCurrent.getStart();
		float widthY=axisYCurrent.getEnd()-axisYCurrent.getStart();
		float pointX=xToAxisX(e.getX());
		float pointY=yToAxisY(e.getY());
		float perCentX=(pointX-axisXCurrent.getStart())/widthX;//X在轴上占百分比
		float perCentY=(pointY-axisYCurrent.getStart())/widthY;//Y在轴上占百分比
		float zoom=1+(e.getWheelRotation()*0.2f);
		
		float xStart=pointX+((widthX*-zoom)*perCentX);
		float xEnd=pointX+((widthX*zoom)*(1-perCentX));
		float yStart=pointY+((widthY*-zoom)*perCentY);
		float yEnd=pointY+((widthY*zoom)*(1-perCentY));

		if(xStart<xEnd){
			axisXCurrent.setStart(xStart);
			axisXCurrent.setEnd(xEnd);
		}
		if(yStart<yEnd){
			axisYCurrent.setStart(yStart);
			axisYCurrent.setEnd(yEnd);
		}

		this.repaint();
	}
//	public void mouseWheelMoved(MouseWheelEvent e) {
//		float widthX=axisXCurrent.getEnd()-axisXCurrent.getStart();
//		float widthY=axisYCurrent.getEnd()-axisYCurrent.getStart();
//		float pointX=xToAxisX(e.getX());
//		float pointY=yToAxisY(e.getY());
//		float zoom=0.5f*(1+(e.getWheelRotation()*0.05f));
//		
//		float xStart=pointX+(widthX*-zoom);
//		float xEnd=pointX+(widthX*zoom);
//		float yStart=pointY+(widthY*-zoom);
//		float yEnd=pointY+(widthY*zoom);
//
//		if(xStart<xEnd){
//			axisXCurrent.setStart(xStart);
//			axisXCurrent.setEnd(xEnd);
//		}
//		if(yStart<yEnd){
//			axisYCurrent.setStart(yStart);
//			axisYCurrent.setEnd(yEnd);
//		}
//
//		this.repaint();
//	}
	
	//#######################################################################################
	//属性
	public String getxUnit() {
		return xUnit;
	}
	public void setxUnit(String xUnit) {
		this.xUnit = xUnit;
	}
	public String getyUnit() {
		return yUnit;
	}
	public void setyUnit(String yUnit) {
		this.yUnit = yUnit;
	}
	public Font getxUnitFont() {
		return xUnitFont;
	}
	public void setxUnitFont(Font xUnitFont) {
		this.xUnitFont = xUnitFont;
	}
	public Font getyUnitFont() {
		return yUnitFont;
	}
	public void setyUnitFont(Font yUnitFont) {
		this.yUnitFont = yUnitFont;
	}
	public Color getxUnitColor() {
		return xUnitColor;
	}
	public void setxUnitColor(Color xUnitColor) {
		this.xUnitColor = xUnitColor;
	}
	public Color getyUnitColor() {
		return yUnitColor;
	}
	public void setyUnitColor(Color yUnitColor) {
		this.yUnitColor = yUnitColor;
	}
	
	public Color getScaleXColor() {
		return scaleXColor;
	}
	public void setScaleXColor(Color scaleXColor) {
		this.scaleXColor = scaleXColor;
	}
	public Font getScaleXFont() {
		return scaleXFont;
	}
	public void setScaleXFont(Font scaleXFont) {
		this.scaleXFont = scaleXFont;
	}
	public Color getScaleYColor() {
		return scaleYColor;
	}
	public void setScaleYColor(Color scaleYColor) {
		this.scaleYColor = scaleYColor;
	}
	public Font getScaleYFont() {
		return scaleYFont;
	}
	public void setScaleYFont(Font scaleYFont) {
		this.scaleYFont = scaleYFont;
	}
	public Font getToolTipTextFont() {
		return toolTipTextFont;
	}
	public void setToolTipTextFont(Font toolTipTextFont) {
		this.toolTipTextFont = toolTipTextFont;
	}
	public Color getToolTipTextColor() {
		return toolTipTextColor;
	}
	public void setToolTipTextColor(Color toolTipTextColor) {
		this.toolTipTextColor = toolTipTextColor;
	}
	public DecimalFormat getScaleFormat() {
		return scaleFormat;
	}
	public void setScaleFormat(DecimalFormat scaleFormat) {
		this.scaleFormat = scaleFormat;
	}
	
	public void addCurveListeners(CurveListener listener){
		listeners.add(listener);
	}
	public void removeCurveListener(CurveListener listener){
		listeners.remove(listeners);
	}
	public void addCurveMouseListeners(CurveMouseListener listener){
		curveMouseListeners.add(listener);
	}
	public void removeCurveMouseListeners(CurveMouseListener listener){
		curveMouseListeners.remove(listener);
	}
	
	public Color getSelectAreaColor() {
		return selectAreaColor;
	}
	public void setSelectAreaColor(Color selectAreaColor) {
		this.selectAreaColor = selectAreaColor;
	}
	public String getToolTipText() {
		return toolTipText;
	}
	public void setToolTipText(String toolTipText) {
		this.toolTipText = toolTipText;
	}
	public Color getAxisXColor() {
		return axisXColor;
	}
	public void setAxisXColor(Color axisXColor) {
		this.axisXColor = axisXColor;
	}
	public Color getAxisYColor() {
		return axisYColor;
	}
	public void setAxisYColor(Color axisYColor) {
		this.axisYColor = axisYColor;
	}
	public Color getGridXColor() {
		return gridXColor;
	}
	public void setGridXColor(Color gridXColor) {
		this.gridXColor = gridXColor;
	}
	public Color getGridYColor() {
		return gridYColor;
	}
	public void setGridYColor(Color gridYColor) {
		this.gridYColor = gridYColor;
	}
	public Margin getMargin() {
		return margin;
	}

	public Scale getAxisX() {
		return axisX;
	}

	public Scale getAxisY() {
		return axisY;
	}

	public Scale getAxisXCurrent() {
		return axisXCurrent;
	}
	public Scale getAxisYCurrent() {
		return axisYCurrent;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public Color getTitleColor() {
		return titleColor;
	}

	public void setTitleColor(Color titleColor) {
		this.titleColor = titleColor;
	}

	public Font getTitleFont() {
		return titleFont;
	}

	public void setTitleFont(Font titleFont) {
		this.titleFont = titleFont;
	}

	public String getTitleRight() {
		return titleRight;
	}

	public void setTitleRight(String titleRight) {
		this.titleRight = titleRight;
	}

	public Color getTitleRightColor() {
		return titleRightColor;
	}

	public void setTitleRightColor(Color titleRightColor) {
		this.titleRightColor = titleRightColor;
	}

	public Font getTitleRightFont() {
		return titleRightFont;
	}

	public void setTitleRightFont(Font titleRightFont) {
		this.titleRightFont = titleRightFont;
	}

	public String getExplainText() {
		return explainText;
	}

	public void setExplainText(String explainText) {
		this.explainText = explainText;
	}

	public Color getExplainTextColor() {
		return explainTextColor;
	}

	public void setExplainTextColor(Color explainTextColor) {
		this.explainTextColor = explainTextColor;
	}

	public Font getExplainTextFont() {
		return explainTextFont;
	}

	public void setExplainTextFont(Font explainTextFont) {
		this.explainTextFont = explainTextFont;
	}

	public boolean isShowCross() {
		return showCross;
	}

	public void setShowCross(boolean showCross) {
		this.showCross = showCross;
	}

	public Color getCrossAcrossColor() {
		return crossAcrossColor;
	}

	public void setCrossAcrossColor(Color crossAcrossColor) {
		this.crossAcrossColor = crossAcrossColor;
	}

	public Color getCrossVerticalColor() {
		return crossVerticalColor;
	}

	public void setCrossVerticalColor(Color crossVerticalColor) {
		this.crossVerticalColor = crossVerticalColor;
	}

	public Color getCrossAcrossTextColor() {
		return crossAcrossTextColor;
	}

	public void setCrossAcrossTextColor(Color crossAcrossTextColor) {
		this.crossAcrossTextColor = crossAcrossTextColor;
	}

	public Color getCrossVerticalTextColor() {
		return crossVerticalTextColor;
	}

	public void setCrossVerticalTextColor(Color crossVerticalTextColor) {
		this.crossVerticalTextColor = crossVerticalTextColor;
	}

	public DecimalFormat getCrossTextFormat() {
		return crossTextFormat;
	}

	public void setCrossTextFormat(DecimalFormat crossTextFormat) {
		this.crossTextFormat = crossTextFormat;
	}

	public Font getCrossFont() {
		return crossFont;
	}

	public void setCrossFont(Font crossFont) {
		this.crossFont = crossFont;
	}
}
